//		ID : Xerxes
//      "I have not failed, I have just found 10000 ways that won't work.
//


#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>

#include <ctime>
#include <cassert>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
#include <cstring>
#include <cstdlib>

using namespace std;

#define VI vector< int >
#define CI( x ) scanf("%d",&x)
#define CL( x ) scanf("%lld",&x)
#define CD( x ) scanf("%lf",&x )
#define fo(i,st,ed) for(int i = st ; i < ed ; ++i )
#define foE(i,st,ed) for(int i = st ; i <= ed ; ++i )
#define foit(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); i++)
#define bip system("pause")
#define Int long long
#define pb push_back
#define SZ(X) (int)(X).size()
#define LN(X) (int)(X).length()
#define mk make_pair
#define f first
#define s second
#define SET( ARRAY , VALUE ) memset( ARRAY , VALUE , sizeof(ARRAY) )
#define tp pair< int, pair<int,int> >
#define mmk( x, y , z ) mk( x, mk( y, z ) )

inline void wait( double seconds ){
    double endtime = clock()+( seconds* CLOCKS_PER_SEC );
    while( clock() < endtime ){
        ;
    }
}
const int Max = (int)1e9;
const int inf = (int)110;
int root[ inf+10 ];
int rank[ inf+10 ];
inline void _Set(){
    fo(i,0,inf){
        root[i]=i;
        rank[i]=0;
    }
}
inline int _Find(int x){
    if( x!= root[x] ){
        root[x] = _Find(root[x]);
    }
return root[x];
}
inline void _Union(int x, int y){
    int rx = _Find(x);
    int ry = _Find(y);

    if( rank[rx] > rank[ry] ){
        root[ry] = rx;
    }
    else{
        root[rx] = ry;
    }
    if( rank[rx]==rank[ry] ){
        rank[ry]+=1;
    }
}

int k;
int n,e; // node edges
struct NODE{
	int x,y,c;
	NODE(int x_, int y_,int c_):
	x(x_),y(y_),c(c_){;}
};
vector<  tp > pt;
vector< NODE > edges;
map< tp , int > mp;
inline bool cmp(NODE A, NODE B){
	return A.c < B.c;
}
inline void read(){
	CI(n);
	CI(e);
	int x,y,c;
	mp.clear();
	edges.clear();
	
	fo(i,0,e){
		CI(x);
		CI(y);
		CI(c);
		mp[ mmk(x,y,c) ]+=1;
		edges.pb( NODE(x,y,c) );
		
	}
	sort(edges.begin(),edges.end(), cmp);
	
}
inline int mst(){
	_Set();
	int cost=0;
	int i,j;
	pt.clear();
	for(i=0,j=0; i<e; ++i){
		int x = edges[i].x;
		int y = edges[i].y;
		int c = edges[i].c;
		if( _Find(x)!=_Find(y) ){
			_Union(x,y);
			pt.pb( mmk(x,y,c) );
			cost+= c;
			++j;
		}
	}
	if( j!= n-1 ){
		return Max;
	}
return cost;	
}
inline int next_mst( ){
	_Set();
	
	int cost=0;
	int i,j;
	for(i=0,j=0; i<e; ++i){
		int x = edges[i].x;
		int y = edges[i].y;
		int c = edges[i].c;
		if( mp[ mmk(x,y,c) ]<=0 )continue;
		if( _Find(x)!=_Find(y) ){
			_Union(x,y);
			++j;
			cost+=c;
		}
	}
	if( j!=n-1 ){
		return Max;
	}
return cost;
}
inline void proc(){
	
	int best_mst = mst();
	if( best_mst == Max ){
		printf("Case #%d : No way\n",k);
		return ;
	}
	int second_best_mst = Max;
	
	foit(i,pt){
		int x = i->f;
		int y = i->s.f;
		int c = i->s.s;
		
		mp[ mmk(x,y,c) ]-=1;
		
		int var = next_mst();
		second_best_mst = min( second_best_mst, var );
		mp[ mmk(x,y,c) ]+=1;
		
		
	}
	if( second_best_mst == Max ){
		printf("Case #%d : No second way\n",k);
		return ;
	}
	printf("Case #%d : %d\n",k,second_best_mst);
}
int main(){
    #ifndef ONLINE_JUDGE
        freopen("in","rt",stdin);
    #endif
    int cases=1;
    for( CI(cases),k=1 ; cases ; --cases,++k ){
        read();
        proc();
    }

return 0;
}

